﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MainPanel : MonoBehaviour
{
    public ScoreViewController scoreViewController;
    public INativeManager nativeManager { get; set; }
    NativeCallback nativeCallback;

    public Image recordButton;
    public Button switchButton;
    public Button playButton;
    public Button stopPlayButton;

    public Sprite recordSpr;
    public Sprite stopRecordSpr;

    public Text freqText;

    public bool isRecording = false;
    bool recordMode = true;


    String[] files = { "test.json", "furelise.json" };
    // Start is called before the first frame update
    void Start()
    {
        var cs = GetComponentInChildren<CanvasScaler>();
        //scoreViewController.Init((int)cs.referenceResolution.x,(int)cs.referenceResolution.y);
        scoreViewController.Init(720, 1280);
        scoreViewController.ShowScore( files[0], GlobalConfig.DEBUG_RECORDTRACK);

        updateRecordShow(true);

        nativeCallback = new GameObject("NativeCallback").AddComponent<NativeCallback>();
        nativeCallback.onDetectFreq = this.OnFrequencyDetected;

#if UNITY_ANDROID
        this.nativeManager = new AndroidNativeManager();
#endif
    }

    public void stopRecord()
    {
        Debug.Log("stop record");
        isRecording = false;
        //AubioHelper.getInstance().stopRecord();
        scoreViewController.Stop();
    }
    public void startRecord()
    {
        Debug.Log("start record");

        countDownEnd = false;
        StartCoroutine(CountDown(() =>
        {
            countDownEnd = true;

            scoreViewController.Play(!GlobalConfig.DEBUG_PLAYMUSIC, DoStopRecord);
        }));
    }

    IEnumerator CountDown(Action onEnd)
    {
        for(int i=3;i>=1; i--)
        {
            yield return new WaitForSeconds(1);


        }
        onEnd?.Invoke();
    }

        
    float m_LastClickStopRecordTime;
    public void OnClickRecord()
    {
        if (!isRecording)
        {
            if (true)//ContextCompat.checkSelfPermission(this,  Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)
            {
                isRecording = true;

                startRecord();

                showStopBtn();
            }
            else
            {
                Debug.LogError("no permission!");
                //ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.RECORD_AUDIO }, MY_PERMISSION_REQUEST_CODE);
            }
        }
        else
        {
            DoStopRecord();

            m_LastClickStopRecordTime = Time.time;
            Debug.Log("OnClickStartRecord: stop record  time:" + m_LastClickStopRecordTime);
        }
    }

    void DoStopRecord()
    {
        if (isRecording)
        {
            stopRecord();
            showRecordBtn();
        }
    }

    public void OnClickSwitch()
    {
        if (Time.time - m_LastClickStopRecordTime < 1)
            return;

        recordMode = !recordMode;
        updateRecordShow(recordMode);
        this.scoreViewController.UpdateShowRecordTrack(GlobalConfig.DEBUG_RECORDTRACK);
    }
    void updateRecordShow(bool showRecord)
    {
        if (showRecord)
        {
            showRecordBtn();
            this.switchButton.GetComponentInChildren<Text>().text = "切到音乐";
            this.recordButton.gameObject.SetActive(true);
            this.playButton.gameObject.SetActive(false);
            this.stopPlayButton.gameObject.SetActive(false);
        }
        else
        {
            this.switchButton.GetComponentInChildren<Text>().text = "切到录制";
            this.recordButton.gameObject.SetActive(false);
            this.playButton.gameObject.SetActive(true);
            this.stopPlayButton.gameObject.SetActive(true);
        }
    }
    public void OnClickPlay()
    {
        Debug.Log("OnClickPlay!");
        this.scoreViewController.Play(false, null);
    }
    public void OnClickStop()
    {
        Debug.Log("OnClickStop!");
        this.scoreViewController.Stop();
    }

    void showRecordBtn()
    {
        //Log.d(TAG, "showRecordBtn!");
        this.recordButton.sprite = recordSpr; 
    }
    void showStopBtn()
    {
        //Log.d(TAG, "showStopBtn!");
        this.recordButton.sprite = stopRecordSpr;
    }

    int index;
    public void OnClickChange()
    {
        if (Time.time - m_LastClickStopRecordTime < 1)
            return;

        if (isRecording)
            stopRecord();
        index++;
        index %= files.Length;
        this.scoreViewController.ShowScore(files[index], GlobalConfig.DEBUG_RECORDTRACK);
    }

    void OnFrequencyDetected(float frequency)
    {
        if (GlobalConfig.DEBUG_RECORDTRACK)
            if (freqText)
                freqText.text = frequency.ToString();

        freqQueue.Add(frequency);
        if (freqQueue.Count > queueSaveFrame)
            freqQueue.RemoveAt(0);

        if (frequency > 0)
        {
            Debug.Log("run: frequency:"+frequency);
        }

        if (countDownEnd)
        {
            for (int i = 0; i < freqQueue.Count; i++)
            {
                if (i <= queueSaveFrame - noteNeedFreqStayFrame)
                {
                    float ele = freqQueue.Count;
                    if (ele > 0)
                    {
                        int goodCount = 1;
                        for (int j = i + 1; j < freqQueue.Count; j++)
                        {
                            bool fit = Mathf.Abs(freqQueue[j] - ele) < 12;
                            if (fit)
                                goodCount++;
                            if (goodCount >= noteNeedFreqStayFrame)
                                break;
                        }
                        if (goodCount >= noteNeedFreqStayFrame)
                        {
                            int midinote = ScoreViewController.Frequency2Note(ele);
                            if (midinote != lastDetectNote)
                            {
                                int[] notes = ScoreViewController.GetNoteWithFrequency(FM_ClefValue.TREBLE, frequency);
                                lastDetectNote = midinote;
                                Debug.Log("检测到音符频率:" + frequency + " 由音高:" + midinote + " 计算得note:" + notes[0] + " oct:" + notes[1] + " acc:" + notes[2]);
                                scoreViewController.AddRecordNote(frequency);
                            }
                            break;
                        }
                    }
                }
            }

            m_lastFrequency = frequency;

        }
    }
    bool countDownEnd;
    List<float> freqQueue = new List<float>(); 
    int queueSaveFrame = 7;
    int noteNeedFreqStayFrame = 4;
    float m_lastFrequency;
    int lastDetectNote;
    // Update is called once per frame
    void Update()
    {
        if (isRecording)
        {
            this.nativeManager?.RequestFrequency();// AubioHelper.getInstance().getPitch();
        }
        if (Time.frameCount % 60 == 0)
        {
            scoreViewController.scoreView.UpdateSignShow(scoreViewController.scoreCanvas);
        }
    }
}
